This invention relates generally to computer technologies, and more particularly to providing a method and apparatus to combine scattered buffer addresses into a contiguous virtual address space.
A computer system typically includes a processor, a chipset, a main memory and a number of peripheral components. Data may be transferred between the processor, the main memory and the peripheral components within a computer system. Typically, data is transferred between the main memory and other components within the computer system via a memory controller hub of the chipset. Read requesters, such as peripheral components, request data from the main memory or other computer components; these requests for data are commonly called read requests. Each read request retrieves a cache of data, often called a read completion, from the main memory.
Due to innovations in computer technologies, such as high-speed microprocessors running at 10 GHz, the existing parallel input/output interconnect, Peripheral Component Interconnect (“PCI”) developed over ten years ago can no longer meet the demands for high speed and bandwidth. To cope with the demands for high speed and bandwidth, serial input/output interconnect has been developed. The latest serial input/output interconnect is Peripheral Component Interconnect Express™ (“PCI Express™” is a trademark of the PCI-Special Interest Group), which is the third generation of input/output interconnect. PCI Express™ is a high-speed serial interconnect, capable of sending multiple read completions for one read request. On PCI Express™, a large read request to retrieve data from the memory results in a large read completion which then may be divided into a plurality of smaller read completions. Each read completion returns data that partially satisfies the read request.
Inbound read completion data for a plurality of outstanding PCI Express™ read requests can be completed in any order in reference to the individual reads, but each read completion of the individual read request must be completed in order. As mentioned above, these read completions can be broken into multiple smaller read completions delivered to their destinations at varying time intervals. The data contained in each read completion must be combined at the destination and delivered as a single chunk of memory to the application layer requester, e.g., the peripheral component.
A typical approach to outputting the read completion data is to handle one read completion at a time. In other words, when the memory controller hub of the chipset receives a read completion, it waits until a PCI Express™ port is not busy to send the read completion via the PCI Express™ port to the read requester. Read completions are sent via the PCI Express™ port one at a time at a fixed size, even though multiple read completions can be combined into one larger completion. The former approach is adopted because it is simple and fair between multiple requesters. However, this approach is very inefficient because the bandwidth of the PCI Express™ port is not fully utilized, leading to decreases in data output efficiency.
One current solution involves reserving a corresponding amount of space in a buffer for each read request before issuing the request. The drawback of this option is that requests cannot be sent until there is enough contiguous address space in the potentially highly fragmented memory space of the buffer, which increases latency for all requests, in particular larger requests.
Another current solution is to create a linked list of buffer addresses as read completion data arrives so the data can be read out in order. When the data is read out to the read requester, the first data portion includes a link including directions to the next data potion. In this way, the read completion data may be broken into small components and stored throughout a fragmented memory space. However, a drawback of this option is that there is no ability to access any particular portion of the originally requested data at any time without first walking through the list to find the link to the location where that portion of the read data is stored.
It would be desirable/advantageous to be able to store read completion data in various locations throughout a buffer and to be able to retrieve any particular portion of the read completion data at any time without having to first walk through a linked list.